// MSimplePlot.h: Schnittstelle f�r die Klasse MSimplePlot.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MSIMPLEPLOT_H__FA540012_E297_45ED_817E_42CC94DE924E__INCLUDED_)
#define AFX_MSIMPLEPLOT_H__FA540012_E297_45ED_817E_42CC94DE924E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#include <QtCore>
#include <QtGui>
#include <QColor>

//#include "RingBuffer.h"
#include <QQueue>

template<class T>

/// This class is a derivative of QQueue to make a ring buffer
class RingBuffer  : public QQueue<T>
{
    public:
        RingBuffer(int size = 10):maxSize(size), T_min(0), T_max(0){
        };
        virtual ~RingBuffer(){};

    public:
        void enqueue(const T &t){

            if(this->size()==0){//initialisation for the max min
                T_max = t;
                T_min = t;
            }

            if(this->size()>maxSize){//need to get rid of the oldest datum
                QQueue<T>::dequeue();
            }
        
        //store it
            QQueue<T>::enqueue(t);

        //and calc the new max mins - we have to do this as we may have removed the max/min value in the dequeue() above
            T_max = QList<T>::at(0);//init
            T_min = QList<T>::at(0);//init
            for(int i=0; i<this->size(); ++i){
                if(QList<T>::at(i)>=T_max) T_max = QList<T>::at(i);
                if(QList<T>::at(i)<=T_min) T_min = QList<T>::at(i);
            }
        }

        void setSize(int newSize){maxSize = newSize;};

    private:
        T T_min;
        T T_max;
        int maxSize;
    public:
        T& minimum(){return T_min;};
        T& maximum(){return T_max;};
};



/// can make this class a little more general by adding units suffixes (i.e. setXUnitSuffix(const QString text); useage: setXUnitSuffix("kms");//"min", //"time (s)"
///could make a deault enum units... but that would never have enough units! 
///need colours, maybe plot styles
class MSimplePlot : public QLabel
{
    Q_OBJECT
            Q_PROPERTY(QColor TextColor READ textColor WRITE setTextColor DESIGNABLE true)
            Q_PROPERTY(QString XLabel READ xLabel WRITE setXlabel DESIGNABLE true)
            Q_PROPERTY(QString YLabel READ yLabel WRITE setYlabel DESIGNABLE true)
            Q_PROPERTY(int NumOfElements READ numElements WRITE setNumElements DESIGNABLE true )
public:
	MSimplePlot(int dataLength = 60, QWidget *parent = 0);
	virtual ~MSimplePlot();

protected:
    QColor m_textColor;
    void paintEvent(QPaintEvent *event);

private:
	//the pixels
	QVector<QPointF> pixels;
	RingBuffer<double> xdata;
	RingBuffer<double> ydata;

    ///some default colours
    const QColor StandardRedFill;//( 165, 0, 33, 255 );//
    const QColor StandardBlueFill;//( 51, 51, 153, 255 );//
    const QColor StandardTextColor;//(Qt::yellow);//
    const QColor MiriamBackgroundColor;//( 0, 51, 0, 255 );//the dark green background
    const QColor MiriamMiddlegroundColor;//( 0, 102, 0, 255 );//the mid green used for some panels
    const QColor MiriamBorderColor;//(0, 255, 0, 255);//the bright green borders

public:
	//should not really use the default argument here - it's more consistant to use two functions
//	void update(double x, double y);
//	void update(double y);
//	because otherwise the order of the argument is not really 'standard' update(y), update(y, x), update(x, y);
	void update(double y, double x=0);
private:
	bool m_showTexts;
	QString m_xAxisText;
	QString m_yAxisText;
    int m_numElements;
public:
	inline void setAxesTexts(const QString xAxisText, const QString yAxisText){m_xAxisText = xAxisText; m_yAxisText = yAxisText;}
	inline void showAxesTexts(const bool showTexts = true){m_showTexts = showTexts;}
    const QColor & textColor() const;
    void setTextColor(QColor textColor);
    const QString & xLabel() const;
    const QString & yLabel() const;
    void setXlabel(QString label);
    void setYlabel(QString label);
    const int numElements() const;
    void setNumElements(int elements);
};

#endif // !defined(AFX_MSIMPLEPLOT_H__FA540012_E297_45ED_817E_42CC94DE924E__INCLUDED_)
